```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Redis集群模式详解 | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #2d3748;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .code-block {
            background-color: #2d3748;
            color: #f7fafc;
            border-left: 4px solid #667eea;
        }
        .cluster-diagram {
            background-color: #f8fafc;
            border-radius: 0.5rem;
            padding: 1.5rem;
        }
        .card {
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
        }
        .highlight-box {
            background-color: #ebf4ff;
            border-left: 4px solid #4299e1;
        }
        .mode-icon {
            color: #667eea;
            font-size: 2rem;
            margin-bottom: 1rem;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-5xl text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6">Redis集群模式深度解析</h1>
            <p class="text-xl md:text-2xl mb-8">高性能、高可用的分布式缓存解决方案</p>
            <div class="flex justify-center space-x-4">
                <a href="#master-slave" class="bg-white text-indigo-600 hover:bg-gray-100 px-6 py-3 rounded-lg font-medium transition duration-300">主从模式</a>
                <a href="#sentinel" class="bg-indigo-700 hover:bg-indigo-800 text-white px-6 py-3 rounded-lg font-medium transition duration-300">哨兵模式</a>
                <a href="#cluster" class="bg-white text-indigo-600 hover:bg-gray-100 px-6 py-3 rounded-lg font-medium transition duration-300">Cluster模式</a>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl py-12 px-4">
        <!-- Introduction -->
        <section class="mb-16">
            <div class="highlight-box p-6 rounded-lg mb-8">
                <h2 class="text-2xl font-bold mb-4 text-gray-800">Redis集群的必要性</h2>
                <p class="mb-4">单机版Redis存在读写瓶颈的问题，为了应对高并发、大数据量的场景，Redis支持三种集群模式：</p>
                <ol class="list-decimal pl-6 space-y-2">
                    <li><strong>主从模式</strong> - 数据备份，读写分离</li>
                    <li><strong>哨兵模式</strong> - 主从+哨兵，自动故障转移</li>
                    <li><strong>Cluster模式</strong> - 分片集群，包含主从和哨兵功能</li>
                </ol>
            </div>
        </section>

        <!-- Master-Slave Mode -->
        <section id="master-slave" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="mode-icon">
                    <i class="fas fa-server"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">Redis主从模式</h2>
            </div>
            
            <div class="card bg-white p-6 rounded-lg shadow-md mb-8">
                <h3 class="text-xl font-semibold mb-4 text-gray-700">主从复制原理</h3>
                <p class="mb-4">主从复制是一种数据备份的方案。使用两个或以上相同的数据库，将一个数据库当做主数据库，而另一个数据库当做从数据库。在主数据库中进行相应操作时，从数据库记录下所有主数据库的操作，使其二者一模一样。</p>
                
                <div class="grid md:grid-cols-2 gap-8 mb-6">
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">优点</h4>
                        <ul class="list-disc pl-6 space-y-2">
                            <li>数据冗余，实现数据备份</li>
                            <li>读写分离，分担读压力</li>
                            <li>避免单点故障</li>
                        </ul>
                    </div>
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">特点</h4>
                        <ul class="list-disc pl-6 space-y-2">
                            <li>主数据库可读写，从数据库只读</li>
                            <li>一个master可拥有多个slave</li>
                            <li>slave挂了不影响其他节点</li>
                            <li>master挂了后需要手动处理</li>
                        </ul>
                    </div>
                </div>
                
                <div class="mb-6">
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1705390668234-623b20a4-3d9b-4118-bded-2f5c68957b00.png" alt="Redis主从模式架构图" class="w-full rounded-lg shadow">
                </div>
                
                <div class="grid md:grid-cols-2 gap-8">
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">全量复制</h4>
                        <ol class="list-decimal pl-6 space-y-2">
                            <li>从服务器连接主服务器，发送SYNC命令</li>
                            <li>主服务器执行BGSAVE生成RDB文件</li>
                            <li>主服务器发送快照文件给从服务器</li>
                            <li>从服务器载入快照文件</li>
                            <li>主服务器发送缓冲区中的写命令</li>
                        </ol>
                    </div>
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">增量复制</h4>
                        <p>当master服务器有数据更新时，会立即同步到所有的slave服务器。主服务器每执行一个写命令就会向从服务器发送相同的写命令。</p>
                    </div>
                </div>
            </div>
            
            <div class="card bg-white p-6 rounded-lg shadow-md">
                <h3 class="text-xl font-semibold mb-4 text-gray-700">Docker搭建主从模式</h3>
                <pre class="code-block p-4 rounded-lg overflow-x-auto mb-4"><code class="language-yaml">version: "3.1"
services:
  redis1:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis1
    ports:
      - 7001:6379
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis2:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis2
    ports:
      - 7002:6379
    volumes:
      - ./conf/redis2.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]
  redis3:
    image: daocloud.io/library/redis:5.0.7
    restart: always
    container_name: redis3
    ports:
      - 7003:6379
    volumes:
      - ./conf/redis3.conf:/usr/local/redis/redis.conf
    links:
      - redis1:master
    command: ["redis-server","/usr/local/redis/redis.conf"]</code></pre>
                
                <h4 class="font-medium mb-3 text-gray-700">配置文件</h4>
                <pre class="code-block p-4 rounded-lg overflow-x-auto"><code class="language-nginx"># redis1.conf master
requirepass root

# redis2.conf slave
replicaof master 6379 
masterauth root 

# redis3.conf slave
replicaof master 6379 
masterauth root</code></pre>
            </div>
        </section>

        <!-- Sentinel Mode -->
        <section id="sentinel" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="mode-icon">
                    <i class="fas fa-shield-alt"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">Redis哨兵模式</h2>
            </div>
            
            <div class="card bg-white p-6 rounded-lg shadow-md mb-8">
                <h3 class="text-xl font-semibold mb-4 text-gray-700">哨兵模式概述</h3>
                <p class="mb-4">主从模式的弊端就是不具备高可用性，当master挂掉以后，Redis将不能再对外提供写入操作。哨兵机制是一种容灾方案。</p>
                <p class="mb-4">哨兵实则是一个在特殊模式下的Redis服务器，用一个或者多个哨兵来监视Master是否在正常执行任务，一旦哨兵发现Master不可用时，就找到一个合适的Slave成为Master。</p>
                
                <div class="mb-6">
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1705391010103-f4840333-86a7-4f78-b036-0f31df4be2c3.png" alt="Redis哨兵模式架构图" class="w-full rounded-lg shadow">
                </div>
                
                <h4 class="font-medium mb-3 text-gray-700">哨兵功能</h4>
                <ul class="list-disc pl-6 space-y-2 mb-6">
                    <li>监控主数据库和从数据库是否运行正常</li>
                    <li>Master出现故障后自动将Slave转化为主数据库</li>
                </ul>
                
                <div class="grid md:grid-cols-2 gap-8">
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">Docker配置</h4>
                        <pre class="code-block p-4 rounded-lg overflow-x-auto"><code class="language-yaml">version: "3.1"
services:
  redis1:
    image: daocloud.io/library/redis:5.0.7
    command: 
      - /bin/sh
      - -c
      - |
        redis-sentinel /data/sentinel.conf
        redis-server /usr/local/redis/redis.conf
    ports:
      - 7001:6379
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
      - ./conf/sentinel1.conf:/data/sentinel.conf</code></pre>
                    </div>
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">哨兵配置文件</h4>
                        <pre class="code-block p-4 rounded-lg overflow-x-auto"><code class="language-yaml"># 哨兵需要后台启动
daemonize yes
# 指定Master节点的ip和端口
sentinel monitor mymaster master 6379 2
# 主节点或副本超时时间
sentinel down-after-milliseconds mymaster 1000
# 连接master密码
sentinel auth-pass mymaster root
# 关闭保护模式
protected-mode no</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="card bg-white p-6 rounded-lg shadow-md">
                <h3 class="text-xl font-semibold mb-4 text-gray-700">哨兵选举过程</h3>
                <div class="grid md:grid-cols-2 gap-8 mb-6">
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">从哨兵中选举leader</h4>
                        <ol class="list-decimal pl-6 space-y-2">
                            <li>单台哨兵认为主节点宕机是主观下线</li>
                            <li>一半以上哨兵认为主节点宕机是客观下线</li>
                            <li>哨兵之间投票，票数过半的哨兵成为leader</li>
                        </ol>
                    </div>
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">从节点中选举leader</h4>
                        <ol class="list-decimal pl-6 space-y-2">
                            <li>选举偏移量最大的从节点</li>
                            <li>选举优先级最大的从节点</li>
                            <li>选择runid最小的从节点</li>
                        </ol>
                    </div>
                </div>
                
                <h4 class="font-medium mb-3 text-gray-700">SpringBoot连接哨兵</h4>
                <pre class="code-block p-4 rounded-lg overflow-x-auto mb-4"><code class="language-yaml">spring:
  redis:
    sentinel:
      nodes:
        - 192.168.147.10:8001
        - 192.168.147.10:8002
        - 192.168.147.10:8003
      master: mymaster</code></pre>
                
                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1705391365538-a1167116-8670-4d3e-8f8b-52f3b8811eec.png" alt="哨兵模式连接原理" class="w-full rounded-lg shadow">
            </div>
        </section>

        <!-- Cluster Mode -->
        <section id="cluster" class="mb-16">
            <div class="flex items-center mb-8">
                <div class="mode-icon">
                    <i class="fas fa-network-wired"></i>
                </div>
                <h2 class="text-3xl font-bold text-gray-800">Redis Cluster模式</h2>
            </div>
            
            <div class="card bg-white p-6 rounded-lg shadow-md mb-8">
                <h3 class="text-xl font-semibold mb-4 text-gray-700">Cluster模式概述</h3>
                <p class="mb-4">当数据量过大到一台服务器存放不下时，需要对存储的数据进行分片。cluster模式将Redis的数据根据一定的规则分配到多台机器。</p>
                
                <div class="mb-6">
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1705391444291-f25d8c26-d45f-4fc9-94cd-ce122ebdc936.png" alt="Redis Cluster模式架构图" class="w-full rounded-lg shadow">
                </div>
                
                <h4 class="font-medium mb-3 text-gray-700">主要特点</h4>
                <ul class="list-disc pl-6 space-y-2 mb-6">
                    <li>采用去中心化的思想，使用hash slot方式将16384个hash slot覆盖到所有节点</li>
                    <li>多个redis节点网络互联，数据共享</li>
                    <li>所有节点都是一主一从</li>
                    <li>支持在线增加、删除节点</li>
                    <li>内部采用哨兵模式进行故障转移</li>
                    <li>集群中至少需要三个主节点才能正常运行</li>
                </ul>
                
                <div class="grid md:grid-cols-2 gap-8">
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">Docker配置</h4>
                        <pre class="code-block p-4 rounded-lg overflow-x-auto"><code class="language-yaml">version: "3.1"
services:
  redis1:
    image: daocloud.io/library/redis:5.0.7
    ports:
      - 7001:7001
      - 17001:17001
    volumes:
      - ./conf/redis1.conf:/usr/local/redis/redis.conf
    command: ["redis-server","/usr/local/redis/redis.conf"]</code></pre>
                    </div>
                    <div>
                        <h4 class="font-medium mb-3 text-gray-700">Redis配置文件</h4>
                        <pre class="code-block p-4 rounded-lg overflow-x-auto"><code class="language-nginx">port 7001
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-announce-ip 192.168.199.109
cluster-announce-port 7001
cluster-announce-bus-port 17001
protected-mode no</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="card bg-white p-6 rounded-lg shadow-md">
                <h3 class="text-xl font-semibold mb-4 text-gray-700">高可用与故障转移原理</h3>
                <ol class="list-decimal pl-6 space-y-2 mb-6">
                    <li>判断节点宕机
                        <ul class="list-disc pl-6 mt-2 space-y-1">
                            <li>主观宕机(pfail)：单个节点认为另一个节点宕机</li>
                            <li>客观宕机(fail)：多个节点认为某个节点宕机</li>
                        </ul>
                    </li>
                    <li>从节点过滤：检查断开连接时间，过滤不合格的从节点</li>
                    <li>从节点选举：根据offset、优先级、runid选举新的主节点</li>
                </ol>
                
                <h4 class="font-medium mb-3 text-gray-700">Java连接Redis集群</h4>
                <pre class="code-block p-4 rounded-lg overflow-x-auto mb-6"><code class="language-java">Set&lt;HostAndPort&gt; nodes = new HashSet&lt;&gt;();
nodes.add(new HostAndPort("192.168.199.109",7001));
// 添加其他节点...

JedisCluster jedisCluster = new JedisCluster(nodes);
String value = jedisCluster.get("b");
System.out.println(value);</code></pre>
                
                <h4 class="font-medium mb-3 text-gray-700">SpringBoot配置</h4>
                <pre class="code-block p-4 rounded-lg overflow-x-auto"><code class="language-yaml">spring:
  redis:
    cluster:
      nodes:
        - 192.168.147.11:7001
        - 192.168.147.11:7002
        - 192.168.147.11:7003
        - 192.168.147.11:7004
        - 192.168.147.11:7005
        - 192.168.147.11:7006</code></pre>
            </div>
        </section>

        <!-- Comparison Section -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 text-gray-800">三种模式对比</h2>
            <div class="grid md:grid-cols-3 gap-6">
                <div class="card bg-white p-6 rounded-lg shadow-md">
                    <h3 class="text-xl font-semibold mb-4 text-center text-indigo-600">主从模式</h3>
                    <ul class="list-disc pl-6 space-y-2">
                        <li>简单易用</li>
                        <li>数据备份</li>
                        <li>读写分离</li>
                        <li>无自动故障转移</li>
                        <li>适合小型应用</li>
                    </ul>
                </div>
                <div class="card bg-white p-6 rounded-lg shadow-md">
                    <h3 class="text-xl font-semibold mb-4 text-center text-indigo-600">哨兵模式</h3>
                    <ul class="list-disc pl-6 space-y-2">
                        <li>自动故障转移</li>
                        <li>高可用性</li>
                        <li>监控机制</li>
                        <li>配置复杂度增加</li>
                        <li>适合中小型应用</li>
                    </ul>
                </div>
                <div class="card bg-white p-6 rounded-lg shadow-md">
                    <h3 class="text-xl font-semibold mb-4 text-center text-indigo-600">Cluster模式</h3>
                    <ul class="list-disc pl-6 space-y-2">
                        <li>数据分片</li>
                        <li>高可用性</li>
                        <li>可扩展性</li>
                        <li>配置最复杂</li>
                        <li>适合大型分布式应用</li>
                    </ul>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-100 py-8">
        <div class="container mx-auto max-w-5xl px-4 text-center">
            <h3 class="text-xl font-semibold mb-2">技术小馆</h3>
            <p class="mb-4">分享前沿技术，探索无限可能</p>
            <a href="http://www.yuque.com/jtostring" class="text-indigo-300 hover:text-white transition duration-300">http://www.yuque.com/jtostring</a>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true
            }
        });
    </script>
</body>
</html>
```